﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Input;

namespace WPFByCoreApp
{


    [StructLayout(LayoutKind.Sequential)]
    public class KeyBoardHookStruct
    {

        public int vkCode;  //定一个虚拟键码。该代码必须有一个价值的范围1至254
        public int scanCode; // 指定的硬件扫描码的关键
        public int flags;  // 键标志
        public int time; // 指定的时间戳记的这个讯息
        public int dwExtraInfo; // 指定额外信息相关的信息
    }

    public class KeyPress_o
    {

        //委托 
        public delegate int HookProc(int nCode, int wParam, IntPtr lParam);
        static int hHook = 0;
        public const int WH_KEYBOARD_LL = 13;
        public const int WH_KEYBOARD = 2;


        //LowLevel键盘截获，如果是WH_KEYBOARD＝2，并不能对系统键盘截取，Acrobat Reader会在你截取之前获得键盘。 
        static HookProc KeyBoardHookProcedure;

        static IntPtr CurPtr;

        //设置钩子 
        [DllImport("user32.dll")]
        public static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId);
        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        //抽掉钩子 
        public static extern bool UnhookWindowsHookEx(int idHook);
        [DllImport("user32.dll")]
        //调用下一个钩子 
        public static extern int CallNextHookEx(int idHook, int nCode, int wParam, IntPtr lParam);
        [DllImport("kernel32.dll")]
        public static extern int GetCurrentThreadId();
        [DllImport("kernel32.dll")]
        public static extern IntPtr GetModuleHandle(string name);

        public static void Hook_Start()
        {
            if (hHook == 0)
            {
                KeyBoardHookProcedure = new HookProc(KeyBoardHookProc);
                CurPtr = GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName);
                hHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyBoardHookProcedure, CurPtr, 0);
                //如果设置钩子失败. 
                if (hHook == 0)
                {
                    Hook_Clear();
                }

                DealCacheHookKeyDownHelper.Instance.Init((key) =>
                {
                    KeyCharTool.keybd_event(((byte)key), 0, 0, 0);
                    KeyCharTool.keybd_event(((byte)key), 0, 0x02, 0);
                }, 300);

            }
        }

        /// <summary>
        /// 取消钩子事件
        /// </summary>
        public static void Hook_Clear()
        {
            bool retKeyboard = true;
            if (hHook != 0)
            {
                retKeyboard = UnhookWindowsHookEx(hHook);
                hHook = 0;
            }
        }

        public static int KeyBoardHookProc(int nCode, int wParam, IntPtr lParam)
        {

            if (nCode >= 0)
            {
                KeyBoardHookStruct kbh = (KeyBoardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyBoardHookStruct));
                Keys k = (Keys)Enum.Parse(typeof(Keys), kbh.vkCode.ToString());

                VirtualKeyCodeEnum k1 = (VirtualKeyCodeEnum)Enum.Parse(typeof(VirtualKeyCodeEnum), wParam.ToString());
                //if (k1 == VirtualKeyCodeEnum.WM_KEYUP)
                Debug.WriteLine("KeyBoardHookProc---Keys:" + k.ToString() + "---flags:" + kbh.flags + "---wParam:" + k1.ToString() + "---nCode:" + nCode + "---date:" + DateTime.Now.ToString("HH:mm.fff"));

                if (k1 == VirtualKeyCodeEnum.WM_SYSKEYDOWN || k1 == VirtualKeyCodeEnum.WM_SYSKEYUP)
                {
                    switch (k)
                    {
                        case Keys.Up:
                        case Keys.Down:
                            DealCacheHookKeyDownHelper.Instance.AddKeyDownQueue(Keys.Tab);
                            break;
                        case Keys.Prior:
                            DealCacheHookKeyDownHelper.Instance.AddKeyDownQueue(Keys.Up);
                            break;
                        case Keys.PageDown:
                            DealCacheHookKeyDownHelper.Instance.AddKeyDownQueue(Keys.Down);
                            break;
                    }
                    DealCacheHookKeyDownHelper.Instance.manuReset.Reset();
                    return 1;
                }
                if (k1 == VirtualKeyCodeEnum.WM_KEYDOWN || k1 == VirtualKeyCodeEnum.WM_KEYUP)
                {
                    DealCacheHookKeyDownHelper.Instance.manuReset.Set();
                }
            }
            return CallNextHookEx(hHook, nCode, wParam, lParam);
        }

    }

    public enum VirtualKeyCodeEnum
    {
        WM_KEYDOWN = 0X100,
        WM_KEYUP = 0X101,
        WM_SYSCHAR = 0X106,
        WM_SYSKEYUP = 0X105,
        WM_SYSKEYDOWN = 0X104,
        WM_CHAR = 0X102

    }

    public enum Keys
    {
        //
        // 摘要:
        //     若要从项值中提取修饰符位掩码。
        Modifiers = -65536,
        //
        // 摘要:
        //     不按任何键。
        None = 0,
        //
        // 摘要:
        //     鼠标左键。
        LButton = 1,
        //
        // 摘要:
        //     鼠标右键。
        RButton = 2,
        //
        // 摘要:
        //     取消键。
        Cancel = 3,
        //
        // 摘要:
        //     鼠标中键 （三个按钮的鼠标）。
        MButton = 4,
        //
        // 摘要:
        //     第一个 x 鼠标按钮 （五个按钮的鼠标）。
        XButton1 = 5,
        //
        // 摘要:
        //     第二个鼠标按钮 （五个按钮的鼠标） x。
        XButton2 = 6,
        //
        // 摘要:
        //     BACKSPACE 键。
        Back = 8,
        //
        // 摘要:
        //     TAB 键。
        Tab = 9,
        //
        // 摘要:
        //     换行键。
        LineFeed = 10,
        //
        // 摘要:
        //     CLEAR 键。
        Clear = 12,
        //
        // 摘要:
        //     RETURN 键。
        Return = 13,
        //
        // 摘要:
        //     ENTER 键。
        Enter = 13,
        //
        // 摘要:
        //     SHIFT 键。
        ShiftKey = 16,
        //
        // 摘要:
        //     CTRL 键。
        ControlKey = 17,
        //
        // 摘要:
        //     ALT 键。
        Menu = 18,
        //
        // 摘要:
        //     PAUSE 键。
        Pause = 19,
        //
        // 摘要:
        //     CAPS LOCK 键。
        Capital = 20,
        //
        // 摘要:
        //     CAPS LOCK 键。
        CapsLock = 20,
        //
        // 摘要:
        //     IME Kana 模式键。
        KanaMode = 21,
        //
        // 摘要:
        //     IME Hanguel 模式密钥。 (保留为了兼容; 使用 HangulMode)
        HanguelMode = 21,
        //
        // 摘要:
        //     IME Hangul 模式键。
        HangulMode = 21,
        //
        // 摘要:
        //     IME Junja 模式键。
        JunjaMode = 23,
        //
        // 摘要:
        //     IME 最终模式键。
        FinalMode = 24,
        //
        // 摘要:
        //     IME Hanja 模式键。
        HanjaMode = 25,
        //
        // 摘要:
        //     IME Kanji 模式键。
        KanjiMode = 25,
        //
        // 摘要:
        //     ESC 键。
        Escape = 27,
        //
        // 摘要:
        //     IME 转换键。
        IMEConvert = 28,
        //
        // 摘要:
        //     IME nonconvert 键。
        IMENonconvert = 29,
        //
        // 摘要:
        //     IME 接受密钥，替换 System.Windows.Forms.Keys.IMEAceept。
        IMEAccept = 30,
        //
        // 摘要:
        //     IME 接受密钥。 已过时，请 System.Windows.Forms.Keys.IMEAccept 相反。
        IMEAceept = 30,
        //
        // 摘要:
        //     IME 模式更改密钥。
        IMEModeChange = 31,
        //
        // 摘要:
        //     SPACEBAR 键。
        Space = 32,
        //
        // 摘要:
        //     PAGE UP 键。
        Prior = 33,
        //
        // 摘要:
        //     PAGE UP 键。
        PageUp = 33,
        //
        // 摘要:
        //     PAGE DOWN 键。
        Next = 34,
        //
        // 摘要:
        //     PAGE DOWN 键。
        PageDown = 34,
        //
        // 摘要:
        //     END 键。
        End = 35,
        //
        // 摘要:
        //     HOME 键。
        Home = 36,
        //
        // 摘要:
        //     LEFT ARROW 键。
        Left = 37,
        //
        // 摘要:
        //     UP ARROW 键。
        Up = 38,
        //
        // 摘要:
        //     RIGHT ARROW 键。
        Right = 39,
        //
        // 摘要:
        //     DOWN ARROW 键。
        Down = 40,
        //
        // 摘要:
        //     SELECT 键。
        Select = 41,
        //
        // 摘要:
        //     PRINT 键。
        Print = 42,
        //
        // 摘要:
        //     EXECUTE 键。
        Execute = 43,
        //
        // 摘要:
        //     PRINT SCREEN 键。
        Snapshot = 44,
        //
        // 摘要:
        //     PRINT SCREEN 键。
        PrintScreen = 44,
        //
        // 摘要:
        //     INS 键。
        Insert = 45,
        //
        // 摘要:
        //     DEL 键。
        Delete = 46,
        //
        // 摘要:
        //     HELP 键。
        Help = 47,
        //
        // 摘要:
        //     0 键。
        D0 = 48,
        //
        // 摘要:
        //     1 键。
        D1 = 49,
        //
        // 摘要:
        //     2 键。
        D2 = 50,
        //
        // 摘要:
        //     3 键。
        D3 = 51,
        //
        // 摘要:
        //     4 键。
        D4 = 52,
        //
        // 摘要:
        //     5 键。
        D5 = 53,
        //
        // 摘要:
        //     6 键。
        D6 = 54,
        //
        // 摘要:
        //     7 键。
        D7 = 55,
        //
        // 摘要:
        //     8 键。
        D8 = 56,
        //
        // 摘要:
        //     9 键。
        D9 = 57,
        //
        // 摘要:
        //     A 键。
        A = 65,
        //
        // 摘要:
        //     B 键。
        B = 66,
        //
        // 摘要:
        //     C 键。
        C = 67,
        //
        // 摘要:
        //     D 键。
        D = 68,
        //
        // 摘要:
        //     E 键。
        E = 69,
        //
        // 摘要:
        //     F 键。
        F = 70,
        //
        // 摘要:
        //     G 键。
        G = 71,
        //
        // 摘要:
        //     H 键。
        H = 72,
        //
        // 摘要:
        //     I 键。
        I = 73,
        //
        // 摘要:
        //     J 键。
        J = 74,
        //
        // 摘要:
        //     K 键。
        K = 75,
        //
        // 摘要:
        //     L 键。
        L = 76,
        //
        // 摘要:
        //     M 键。
        M = 77,
        //
        // 摘要:
        //     N 键。
        N = 78,
        //
        // 摘要:
        //     O 键。
        O = 79,
        //
        // 摘要:
        //     P 键。
        P = 80,
        //
        // 摘要:
        //     Q 键。
        Q = 81,
        //
        // 摘要:
        //     R 键。
        R = 82,
        //
        // 摘要:
        //     S 键。
        S = 83,
        //
        // 摘要:
        //     T 键。
        T = 84,
        //
        // 摘要:
        //     U 键。
        U = 85,
        //
        // 摘要:
        //     V 键。
        V = 86,
        //
        // 摘要:
        //     W 键。
        W = 87,
        //
        // 摘要:
        //     X 键。
        X = 88,
        //
        // 摘要:
        //     Y 键。
        Y = 89,
        //
        // 摘要:
        //     Z 键。
        Z = 90,
        //
        // 摘要:
        //     左 Windows 徽标键 (Microsoft Natural Keyboard)。
        LWin = 91,
        //
        // 摘要:
        //     右 Windows 徽标键 (Microsoft Natural Keyboard)。
        RWin = 92,
        //
        // 摘要:
        //     应用程序密钥 （Microsoft 自然键盘） 中。
        Apps = 93,
        //
        // 摘要:
        //     计算机睡眠键。
        Sleep = 95,
        //
        // 摘要:
        //     数字键盘上的 0 键。
        NumPad0 = 96,
        //
        // 摘要:
        //     数字键盘上的 1 键。
        NumPad1 = 97,
        //
        // 摘要:
        //     数字键盘上的 2 键。
        NumPad2 = 98,
        //
        // 摘要:
        //     数字键盘上的 3 键。
        NumPad3 = 99,
        //
        // 摘要:
        //     数字键盘上的 4 键。
        NumPad4 = 100,
        //
        // 摘要:
        //     数字键盘上的 5 键。
        NumPad5 = 101,
        //
        // 摘要:
        //     数字键盘上的 6 键。
        NumPad6 = 102,
        //
        // 摘要:
        //     数字键盘上的 7 键。
        NumPad7 = 103,
        //
        // 摘要:
        //     数字键盘上的 8 键。
        NumPad8 = 104,
        //
        // 摘要:
        //     数字键盘上的 9 键。
        NumPad9 = 105,
        //
        // 摘要:
        //     乘号键。
        Multiply = 106,
        //
        // 摘要:
        //     加号键。
        Add = 107,
        //
        // 摘要:
        //     分隔符键。
        Separator = 108,
        //
        // 摘要:
        //     减号键。
        Subtract = 109,
        //
        // 摘要:
        //     句点键。
        Decimal = 110,
        //
        // 摘要:
        //     除号键。
        Divide = 111,
        //
        // 摘要:
        //     F1 键。
        F1 = 112,
        //
        // 摘要:
        //     F2 键。
        F2 = 113,
        //
        // 摘要:
        //     F3 键。
        F3 = 114,
        //
        // 摘要:
        //     F4 键。
        F4 = 115,
        //
        // 摘要:
        //     F5 键。
        F5 = 116,
        //
        // 摘要:
        //     F6 键。
        F6 = 117,
        //
        // 摘要:
        //     F7 键。
        F7 = 118,
        //
        // 摘要:
        //     F8 键。
        F8 = 119,
        //
        // 摘要:
        //     F9 键。
        F9 = 120,
        //
        // 摘要:
        //     F10 键。
        F10 = 121,
        //
        // 摘要:
        //     F11 键。
        F11 = 122,
        //
        // 摘要:
        //     F12 键。
        F12 = 123,
        //
        // 摘要:
        //     F13 键。
        F13 = 124,
        //
        // 摘要:
        //     F14 键。
        F14 = 125,
        //
        // 摘要:
        //     F15 键。
        F15 = 126,
        //
        // 摘要:
        //     F16 键。
        F16 = 127,
        //
        // 摘要:
        //     F17 键。
        F17 = 128,
        //
        // 摘要:
        //     F18 键。
        F18 = 129,
        //
        // 摘要:
        //     F19 键。
        F19 = 130,
        //
        // 摘要:
        //     F20 键。
        F20 = 131,
        //
        // 摘要:
        //     F21 键。
        F21 = 132,
        //
        // 摘要:
        //     F22 键。
        F22 = 133,
        //
        // 摘要:
        //     F23 键。
        F23 = 134,
        //
        // 摘要:
        //     F24 键。
        F24 = 135,
        //
        // 摘要:
        //     NUM LOCK 键。
        NumLock = 144,
        //
        // 摘要:
        //     SCROLL LOCK 键。
        Scroll = 145,
        //
        // 摘要:
        //     左的 SHIFT 键。
        LShiftKey = 160,
        //
        // 摘要:
        //     右侧 SHIFT 键。
        RShiftKey = 161,
        //
        // 摘要:
        //     左 CTRL 键。
        LControlKey = 162,
        //
        // 摘要:
        //     右 CTRL 键。
        RControlKey = 163,
        //
        // 摘要:
        //     左 ALT 键。
        LMenu = 164,
        //
        // 摘要:
        //     右 ALT 键。
        RMenu = 165,
        //
        // 摘要:
        //     浏览器后退键 (Windows 2000 或更高版本)。
        BrowserBack = 166,
        //
        // 摘要:
        //     浏览器前进键 (Windows 2000 或更高版本)。
        BrowserForward = 167,
        //
        // 摘要:
        //     浏览器刷新键 (Windows 2000 或更高版本)。
        BrowserRefresh = 168,
        //
        // 摘要:
        //     浏览器停止键 (Windows 2000 或更高版本)。
        BrowserStop = 169,
        //
        // 摘要:
        //     浏览器搜索键 (Windows 2000 或更高版本)。
        BrowserSearch = 170,
        //
        // 摘要:
        //     浏览器收藏夹项 (Windows 2000 或更高版本)。
        BrowserFavorites = 171,
        //
        // 摘要:
        //     浏览器主页键 (Windows 2000 或更高版本)。
        BrowserHome = 172,
        //
        // 摘要:
        //     音量静音键 (Windows 2000 或更高版本)。
        VolumeMute = 173,
        //
        // 摘要:
        //     按下键 (Windows 2000 或更高版本) 卷。
        VolumeDown = 174,
        //
        // 摘要:
        //     向上键 (Windows 2000 或更高版本) 卷。
        VolumeUp = 175,
        //
        // 摘要:
        //     接下来，媒体跟踪键 (Windows 2000 或更高版本)。
        MediaNextTrack = 176,
        //
        // 摘要:
        //     媒体上一曲目键 (Windows 2000 或更高版本)。
        MediaPreviousTrack = 177,
        //
        // 摘要:
        //     媒体停止键 (Windows 2000 或更高版本)。
        MediaStop = 178,
        //
        // 摘要:
        //     在媒体播放暂停键 (Windows 2000 或更高版本)。
        MediaPlayPause = 179,
        //
        // 摘要:
        //     启动邮件键 (Windows 2000 或更高版本)。
        LaunchMail = 180,
        //
        // 摘要:
        //     选择媒体键 (Windows 2000 或更高版本) 中。
        SelectMedia = 181,
        //
        // 摘要:
        //     启动应用程序一个密钥 (Windows 2000 或更高版本)。
        LaunchApplication1 = 182,
        //
        // 摘要:
        //     启动应用程序两个密钥 (Windows 2000 或更高版本)。
        LaunchApplication2 = 183,
        //
        // 摘要:
        //     美国标准键盘 (Windows 2000 或更高版本) 上的 OEM 分号键。
        OemSemicolon = 186,
        //
        // 摘要:
        //     OEM 1 键。
        Oem1 = 186,
        //
        // 摘要:
        //     OEM 加上任何国家/地区键盘 (Windows 2000 或更高版本) 上的键。
        Oemplus = 187,
        //
        // 摘要:
        //     任何国家/地区键盘 (Windows 2000 或更高版本) 上的 OEM 逗号键。
        Oemcomma = 188,
        //
        // 摘要:
        //     减号键任何国家/地区键盘 (Windows 2000 或更高版本) 上 OEM。
        OemMinus = 189,
        //
        // 摘要:
        //     任何国家/地区键盘 (Windows 2000 或更高版本) 上的 OEM 期间键。
        OemPeriod = 190,
        //
        // 摘要:
        //     美国标准键盘 (Windows 2000 或更高版本) 上的 OEM 问号键。
        OemQuestion = 191,
        //
        // 摘要:
        //     OEM 2 键。
        Oem2 = 191,
        //
        // 摘要:
        //     美国标准键盘 (Windows 2000 或更高版本) 上的 OEM 颚化符键。
        Oemtilde = 192,
        //
        // 摘要:
        //     OEM 3 键。
        Oem3 = 192,
        //
        // 摘要:
        //     美国标准键盘 (Windows 2000 或更高版本) 上的 OEM 左括号键。
        OemOpenBrackets = 219,
        //
        // 摘要:
        //     OEM 4 键。
        Oem4 = 219,
        //
        // 摘要:
        //     美国标准键盘 (Windows 2000 或更高版本) 上的 OEM 管道键。
        OemPipe = 220,
        //
        // 摘要:
        //     OEM 5 键。
        Oem5 = 220,
        //
        // 摘要:
        //     美国标准键盘 (Windows 2000 或更高版本) 上的 OEM 右大括号键。
        OemCloseBrackets = 221,
        //
        // 摘要:
        //     OEM 6 键。
        Oem6 = 221,
        //
        // 摘要:
        //     OEM 意见/双精度型引号密钥美式标准键盘 (Windows 2000 或更高版本) 上。
        OemQuotes = 222,
        //
        // 摘要:
        //     OEM 7 键。
        Oem7 = 222,
        //
        // 摘要:
        //     OEM 8 键。
        Oem8 = 223,
        //
        // 摘要:
        //     OEM 尖括号的反斜线按键上 RT 102 键键盘 (Windows 2000 或更高版本)。
        OemBackslash = 226,
        //
        // 摘要:
        //     OEM 102 键。
        Oem102 = 226,
        //
        // 摘要:
        //     处理键键。
        ProcessKey = 229,
        //
        // 摘要:
        //     用来传递 Unicode 字符，就像击键。 数据包键值是用于非键盘输入方法为 32 位虚拟键值的低位字。
        Packet = 231,
        //
        // 摘要:
        //     ATTN 键。
        Attn = 246,
        //
        // 摘要:
        //     CRSEL 键。
        Crsel = 247,
        //
        // 摘要:
        //     EXSEL 键。
        Exsel = 248,
        //
        // 摘要:
        //     ERASE EOF 键。
        EraseEof = 249,
        //
        // 摘要:
        //     播放键。
        Play = 250,
        //
        // 摘要:
        //     缩放键。
        Zoom = 251,
        //
        // 摘要:
        //     留待将来使用的常数。
        NoName = 252,
        //
        // 摘要:
        //     PA1 键。
        Pa1 = 253,
        //
        // 摘要:
        //     CLEAR 键。
        OemClear = 254,
        //
        // 摘要:
        //     从项值中提取键代码的位屏蔽。
        KeyCode = 65535,
        //
        // 摘要:
        //     Shift 键修改键。
        Shift = 65536,
        //
        // 摘要:
        //     CTRL 修改键。
        Control = 131072,
        //
        // 摘要:
        //     ALT 修改键。
        Alt = 262144
    }

    /// <summary>
    /// 键盘和key转换类
    /// </summary>
    public class KeyCharTool
    {
        [DllImport("user32.dll")]
        static extern int MapVirtualKey(uint uCode, uint uMapType);

        [DllImport("user32.dll")]
        public static extern short VkKeyScan(char ch);

        [DllImport("User32.dll")]
        public static extern void keybd_event(byte bVK, byte bScan, Int32 dwFlags, int dwExtraInfo);



        [DllImport("User32.dll", EntryPoint = "GetKeyState")]
        public static extern short GetKeyState(int nVirtKey);

        [DllImport("user32.dll")]
        public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);


        private static char KeyCodeToChar(Keys k)
        {


            int nonVirtualKey = MapVirtualKey((uint)k, 2);
            char mappedChar = Convert.ToChar(nonVirtualKey);
            return mappedChar;


        }

        public static string KeyCodeToStr(Keys k)
        {
            char mappedChar = KeyCodeToChar(k);
            string str = mappedChar.ToString();
            if (Char.IsWhiteSpace(mappedChar) || string.IsNullOrEmpty(str) || mappedChar == '\r' || mappedChar == '\n' || mappedChar == KeyCodeToChar(Keys.F1))
            {
                return k.ToString();
            }
            else
            {


                return str + "";
            }
        }

        public static Key ResolveKey(char charToResolve)
        {
            return KeyInterop.KeyFromVirtualKey(VkKeyScan(charToResolve));
        }

    }

    public class DealCacheHookKeyDownHelper
    {
        #region 成员变量
        private object IsLock = new object();
        private HashSet<Keys> KeySet = new HashSet<Keys>();
        private Action<Keys> DealEvent;
        private int Interval = 1000;


        public ManualResetEvent manuReset;
        #endregion

        #region 单列
        private static DealCacheHookKeyDownHelper _instance;

        public static DealCacheHookKeyDownHelper Instance
        {
            get
            {
                if (_instance == null)
                    _instance = new DealCacheHookKeyDownHelper();
                return _instance;
            }


        }

        #region 构造函数
        private DealCacheHookKeyDownHelper()
        {
            ThreadPool.QueueUserWorkItem(new WaitCallback(BatchDealKeyDown));

            manuReset = new ManualResetEvent(false);
        }

        #endregion
        #endregion

        #region 公共方法
        public void Init(Action<Keys> dealEvent, int interval = 1000)
        {
            DealEvent = dealEvent;
            Interval = interval;

            KeySet = new HashSet<Keys>();
        }


        public bool AddKeyDownQueue(Keys key)
        {

            lock (IsLock)
            {
                KeySet.Add(key);
            }


            return true;



        }

        #endregion

        #region 私有方法

        private void BatchDealKeyDown(object obj)
        {
            while (true)
            {

                if (KeySet.Count > 0)
                {
                    manuReset.WaitOne();

                    lock (IsLock)
                    {
                        if (DealEvent != null)
                        {
                            KeySet.ToList().ForEach(par =>
                            {
                                DealEvent(par);
                            });
                        }
                        KeySet.Clear();
                    }


                    Thread.Sleep(Interval);
                }

                Thread.Sleep(10);
            }


        }
        #endregion
    }

}
